package Api.WxPay.DirectPay;


import Util.HttpUtil;
import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static Util.Tools.MaptoStr;
import static Util.Tools.getMD5;

/**
 * 微信直连支付
 */
public class WxDirectPayApplypay {
    public static void main(String[] args) {
        try {
            // 目标URL
            String url = "https://Pay.Heepay.com/DirectPay/applypay.aspx";
            //MD5密钥，商户后台网关密钥下面第一个
            String key = "852B4A10455E49F280EEFCB1";
            //商户编号，（汇付宝商户内码：七位整数数字）
            String agent_id = "2083328";
            // 获取当前14位时间戳
            Date now = new Date();
            // 创建 SimpleDateFormat 对象，指定日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String timestamp = dateFormat.format(now);

            //固定版本号
            String version = "1";
            String pay_type = "30";
            String agent_bill_id = timestamp;
            String agent_bill_time = timestamp;
            String pay_amt = "0.01";
            /*
            支付后的异步地址，URL参数是以http://或https://开头的完整URL地址(后台处理)，提交的url地址必须外网能访问到，否则无法通知商户。值可以为空，但不可以为null。
             */
            String notify_url = "https://www.baidu.com/";
            String return_url = "https://www.baidu.com/";
            String user_ip = "127_127_12_12";
            String goods_num = "1";
            String goods_name = "商品名称";
            String goods_name1 = URLEncoder.encode(goods_name, "GBK");
            //商户自定义，原样返回,可以为空。要是小程序传固定格式appid
            String remark = "wowowowow";

            /*
            对私分账参数，记录内码:分账金额,记录内码:分账金额。商家后台-分账配置查询-记录内码，分账总金额=订单金额-(订单金额*费率)，金额只传入小数点后2位的值，第三位舍去留在通道里，如对公结算此参数传空（不参与签名）
            String goods_note = "";
            String goods_note1 = URLEncoder.encode(goods_note, "GBK");
            */

            /*
            支付方式，h5表示h5，wxa表示小程序，qr表示扫码（如支付类型为扫码，payment_mode传UnifiedOrder返回二维码url），jsapi表示公众号（微信内拉起），app表示app拉起支付(值均为小写)
            */
            String scene = "h5";

            /*
            收银台=cashier，接口=UnifiedOrder（目前支持小程序，扫码，app）
            */
            String payment_mode = "cashier";
            /*
            银行类型：未知=-1，储蓄卡=0，信用卡=1。
            */
            String bank_card_type = "-1";


            /*
             * meta_option添加在请求参数中（不参与签名）
             * 说明：
             * app包装微信H5（ios/Android）、微信wap
             * ios:(meta_option="{"s":"IOS","n":"应用在App Store中唯一应用名","id":"IOS应用唯一标识"}";)
             * Android:(meta_option="{"s":"Android","n":"应用在安卓分发市场中的应用名","id":"应用在一台设备上的唯一标识在manifest文件里面的声明"}";)
             * WAP网站：(meta_option="{"s":"WAP","n":"WAP网站名","id":"WAP网站的首页URL"}";)WAP网址必须保证公网能正常访问
             * 示例：
             * wap网站：(meta_option="{"s":"WAP","n":"京东官网","id":"https://m.jd.com"}";)
             * s=应用场景
             * n=应用名称（应用名称或者WAP网站名称）
             * id=IOS应用唯一标识或者。Android应用在一台设备上的唯一标识在manifest文件里面的声明或者WAP网站的首页URL
             * 注意：此参数需要GBK编码下base64，然后urlencode。
             * meta_option示例：
             * 原始数据：meta_option={"s":"WAP","n":"京东官网","id":"https://m.jd.com"}
             * 加密后结果：meta_option=eyJzIjoiV0FQIiwibiI6Ir6ptqu52c34IiwiaWQiOiJodHRwczovL20uamQuY29tIn0%3d
             */

            Map<String, String> map = new HashMap<String, String>();
            map.put("s", "1");
            map.put("n", "网站名");
            map.put("id", "首页URL");
            String a = JSON.toJSONString(map);
            // Step 1: 将JSON串编码为GBK格式的字节数组
            byte[] gbkBytes;
            try {
                gbkBytes = a.getBytes("GBk");
            } catch (UnsupportedEncodingException e) {
                System.out.println("不支持的字符集：" + e.getMessage());
                return;
            }
            // Step 2: 对GBK格式的字节数组进行Base64编码
            String base64EncodedString = Base64.getEncoder().encodeToString(gbkBytes);
            String meta_option = URLEncoder.encode(base64EncodedString);



            Map<String, String> parameters = new HashMap<String, String>();

                //拼接待加密参数
            StringBuilder builder = new StringBuilder();
            builder.append("version=");
            builder.append(version);
            builder.append("&agent_id=");
            builder.append(agent_id);
            builder.append("&agent_bill_id=");
            builder.append(agent_bill_id);
            builder.append("&agent_bill_time=");
            builder.append(agent_bill_time);
            builder.append("&pay_type=");
            builder.append(pay_type);
            builder.append("&pay_amt=");
            builder.append(pay_amt);
            builder.append("&notify_url=");
            builder.append(notify_url);
            builder.append("&return_url=");
            builder.append(return_url);
            builder.append("&user_ip=");
            builder.append(user_ip);
            builder.append("&bank_card_type=");
            builder.append(bank_card_type);
            builder.append("&remark=");
            builder.append(remark);
            builder.append("&key=");
            builder.append(key);


            String Date = builder.toString();
            //MD5加密得出签名结果
            String sign = getMD5(Date);


            //拼接请求参数
            parameters.put("version", version);
            parameters.put("scene", scene);
            parameters.put("payment_mode", payment_mode);
            parameters.put("bank_card_type", bank_card_type);
            parameters.put("pay_type", pay_type);
            parameters.put("agent_id", agent_id);
            parameters.put("agent_bill_id", agent_bill_id);
            parameters.put("agent_bill_time", agent_bill_time);
            parameters.put("pay_amt", pay_amt);
            parameters.put("notify_url", notify_url);
            parameters.put("return_url", return_url);
            parameters.put("user_ip", user_ip);
            parameters.put("goods_name", goods_name1);
            parameters.put("goods_num", goods_num);
            parameters.put("remark", remark);
            //parameters.put("goods_note", goods_note1);
            parameters.put("meta_option", meta_option);
            parameters.put("sign", sign);


            //打印请求参数
            String Str = MaptoStr(parameters);
            System.out.println("发送请求数据：-------------------------------->"+ Str);

            String Result = HttpUtil.sendPost2(url, parameters);
            System.out.println("返回响应数据：-------------------------------->"+Result);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}